/*
 * Copyright (c) 2019 Author: Fancyears Milos Malvis @1243093366@qq.com
 * ALL COPYRIGHT REVERSED.
 */

package com.fancyears.encrypt;

import com.auth0.jwt.internal.org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * @Author: Fancyears Milos Malvis
 * @Date: Created in  2019/6/20 15:47
 * @Modified By:
 */
public class RsaUtil2 {
    public static final String PADDING = "RSA/ECB/PKCS1Padding";
    public static final String PROVIDER = "BC";
    public static final Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();

    static {
        Security.addProvider(provider);
    }

    /**
     * 解密数据
     *
     * @param encrypted
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String encrypted, RSAPrivateKey privateKey) throws Exception {
        Cipher cipher;
        try {
            try {
                cipher = Cipher.getInstance(PADDING);
            } catch (Exception e) {
                cipher = Cipher.getInstance(PADDING, PROVIDER);
            }
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
        } catch (GeneralSecurityException e) {
            throw new RuntimeException("RSA algorithm not supported", e);
        }
        String[] blocks = encrypted.split("\\s");
        StringBuffer result = new StringBuffer();

        try {
            for (int i = 0; i < blocks.length; i++) {
                byte[] data = Base64.decodeBase64(blocks[i].getBytes());
                byte[] finalBytes = cipher.doFinal(data);
                result.append(new String(finalBytes, "UTF-8"));
            }
        } catch (GeneralSecurityException e) {
            throw new RuntimeException("Decrypt error", e);
        }
        return result.toString();
    }

    /**
     * 通过私钥PEM文件流还原私钥
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws IOException
     */
    public static RSAPrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
//        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer publicKey = new StringBuffer();
        publicKey.append("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCLifYDnKgcMXPG5dbnQrhOSDQRl1bdhM3lB0h7k+sF/J+9b07Ky9Ezdr/9PqsutZCae+8eqiknqLFkX7YyqfJCNt0pTSlQkzH4Xcqmo2sDppcNE+C7rt5U8Ot8YSoylTqOBIL6r5Z2GLP5AXn2jwzr0Ytq5JpH+00d9DhcLyiIRkK3xktqxLUO2gNTh0LBU50oSMEnG2dmP4TnuGec7ob34Fd/mSWYnHDqOdhQc+ksmoF3cHZFYudKD5EW9DyTLFJqee17rBVTqafyke3dpaeB5IpnY/Ton4MOcPAW3tGcnHP/6WkRD1mtJaE4AA89Azvnu+0gJgF3/8PgMz4erzThAgMBAAECggEAEo4/C83qQQ2Gct2fjVM/BRHu8qPoZj7BzoIAboaGC17Ds0I4/RjLcgeJkliiFO0KFLEEZFSGcoKpTEq6BNS6pXl8QYDETLW2QGvghfZXRb4Ceje5e9vOLwd2mSymmuFjTv1kmYd9/6hbTnKW0GXHdxh/bLCHn6jYYXJXiFKxFiXlMb+31Mv/L7v2nEO0yEm2KvpnSlWfsu3mtt51GkQwBf+D0zOwbw8Wx2cEG3fRctsF6QU/zqIAffmW3KV6fnXWmXiZbYuA3s42FzLu/4/Vzh8rwH39V995Vi8pBAkMG0uliLqaMQaFuG0ege7rtFMfX+D0MhXf6cd6ysydK2gwXQKBgQD++2v7XdJOHTuiHb/RSmOtPBKOpzz5yd2eDMhZYTwOyLnHk7Ca94AZtgHVpVYg9OePtNIj1ykVNtJXjN4ehohh7D+XGilLMyOtu/H26YvZJb6UtgaDr5f9aezHUOBSlrPtda0sG5ixUEHT7IRdxRQQilvIxIJyqCHRS6MSiDW5CwKBgQCMGI/2j28gmXYCQ7kE1lxnhBdYk6P4vgc0DvwKkckjX8d7Tw/ihpHunaaAuuwNo7IZca/GjU9RtWoGoFAgz/jUk/0YIb2V3Eid5/z9BP8BcZesNRane1VUTaQN4866lbRU8c5ontiZpc1rn2TZtFzsAOyFcKPDdiUxlKsyI0G1QwKBgQCXuVnewExE6QY0CEm8quw3B/ju47rX0/PIeUi6Tq6jCXPquwoqnD2gjvn2fCSNBc3IaEtmwkAS/IUbTZpaRalfw2lva0TJF4wSdDSdvQjXVKtb6BhmQZVKWL5pN8nTuxMjqJM8HMu2LtCM3z9AYOX4lavaAnyw5zUASmalv2FgUwKBgGMOEuxgalCAcSIUxEMZVeiTSvaEHZIIuosidS77+V2boS4crryaLaCrs0id4b2bGphG++PFkmnRfZAF1eH9apDTukZPxP6q7GVJ3GUCHVPl/znxp3zwBVtAMljn1Am1Q/Yzqp/qgHfS9bW808/iaTktRg7rn77aUF4IIiunJhSFAoGBAOc4OmXe4ajT/xuE15iDo5ScCiHnIH8xRBKLASIQqOKgGwhoUQEPwBJmrZddacip/XnmP0HQIc1NXu18qfKo3j+UBODjgEeY9SkLveXph5daJN/3mnoINehpVCzuXcdO7eHID5In0PeglakgbfhkvFaCHcTfrr7qRV3qZZT6W1EF");
//        String s;
//        while ((s = br.readLine()) != null) {
//            if (s.charAt(0) != '-') {
//                publicKey.append(s + "\r");
//            }
//        }
        byte[] keyBytes = Base64.decodeBase64(publicKey.toString().getBytes());

        return getPrivateKey(keyBytes);
    }

    /**
     * 通过私钥byte[]还原私钥
     *
     * @param keyBytes
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static RSAPrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return (RSAPrivateKey) privateKey;
    }

    public static void main(String[] args) throws Exception {
        System.out.println(decrypt(
                "=egu6ycDUE07KN14E6uyVCjHNfAVdX/asoDQuXC49RDSPoroRlx23yGq531FO3hJ2N9VEjVf1x8aY+M7RUlJ5Za6yTRNw7aUdHAUcVOGITnSb3Z/XGsOZzR/lEiJqL6MwCB2VVA3Avv+FOiNqRTXg8xUJGEUbebopdDhBTcE6C8YiaQkwy9KmJ7D7dHlshf8jcqR4aZmdZ0CJA676/iwoVJQyF57TW4hHvLPwofxYWv1rauo03nJJdpeGCDaWFdaBLGIn5H+G5DRkl+H+Uy3jahIBtlHWySerGvNA2n7E1RxDj7kIF5PHptCGwIdvsvirJoYaHosJ11htUVUmqOL2zA=="
                ,getPrivateKey()));
    }
}
